/*******************************************************************************
 * Copyright (c) 2014-8-25 @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a>.
 * All rights reserved.
 *
 * Contributors:
 *     <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> - initial API and implementation
 ******************************************************************************/
package com.foreveross.project.projectonline.config;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.iff.infra.util.FCS;
import org.iff.infra.util.Logger;
import org.iff.infra.util.StringHelper;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

/**
 * @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> 
 * @since 2014-8-25
 */
@SuppressWarnings("unchecked")
public class AfterAIThreadLocal {

	private final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

	private static AfterAIThreadLocal me = new AfterAIThreadLocal();

	public static AfterAIThreadLocal me() {
		return me;
	}

	public Map<String, Object> put(String key, Object value) {
		Map<String, Object> map = null;
		try {
			Logger.debug(FCS.get("[AfterTxThreadLocal.put][{0}][{1}]", key, value));
			map = threadLocal.get();
			if (map == null) {
				threadLocal.set(new HashMap<String, Object>());
				map = threadLocal.get();
			}
			if (StringUtils.isBlank(key) || value == null) {
				return map;
			}
			Object o = map.get(key);
			if (o != null && o instanceof Set) {
				((Set) o).add(value);
			} else {
				Set<Object> list = new HashSet<Object>();
				list.add(value);
				map.put(key, list);
			}
		} catch (Exception e) {
			Logger.debug(FCS.get("[AfterTxThreadLocal.put][ERROR][{0}][{1}]", key, value), e);
		}
		return map;
	}

	public <T> T get(String key) {
		Map<String, Object> map = threadLocal.get();
		if (map == null) {
			return null;
		}
		return (T) map.get(key);
	}

	public void doCounter() {
		try {
			Map<String, Object> map = threadLocal.get();
			if (map == null || map.isEmpty()) {
				return;
			}
			for (Entry<String, Object> entry : map.entrySet()) {
				if ("COUNTER".equals(entry.getKey())) {
					Object o = entry.getValue();
					if (o instanceof Set) {
						Set<Object> list = (Set<Object>) o;
						for (Object obj : list) {
							addCount(obj);
						}
					}
				}
			}
			map.remove("COUNTER");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void addCount(Object obj) {
		try {
			if ((obj instanceof String[]) && ((String[]) obj).length == 3) {
				String[] params = ((String[]) obj);
				int update = Db
						.update(
								"update TB_COUNTER set VALUE=VALUE+1, UPDATE_TIME=? where CATEGORY=? and TYPE=? and TARGET_ID=? and IS_ENABLE='Y'",
								new Date(), params[0], params[1], params[2]);
				if (update < 1) {
					Db.save("TB_COUNTER", new Record()//
							.set("ID", StringHelper.uuid())//
							.set("CATEGORY", params[0])//
							.set("TYPE", params[1])//
							.set("TARGET_ID", params[2])//
							.set("VALUE", 1)//
							.set("CREATE_TIME", new Date())//
							.set("UPDATE_TIME", new Date())//
							.set("IS_ENABLE", "Y")//
							);
				}
			}
		} catch (Exception e) {
			Logger.warn("[AfterAIThreadLocal.addCount()][ERROR]", e);
		}
	}
}
